home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2001 December / pcwk12201b.iso / Wersje pelne i specjalne / Winamp 2.77 i 3.0beta / wasabi-sdk_beta1.exe / studio / common / tabsheet.cpp < prev    next >
C/C++ Source or Header  |  2001-10-08  |  10KB  |  391 lines

  1. /*
  2.  
  3.   Nullsoft WASABI Source File License
  4.  
  5.   Copyright 1999-2001 Nullsoft, Inc.
  6.  
  7.     This software is provided 'as-is', without any express or implied
  8.     warranty.  In no event will the authors be held liable for any damages
  9.     arising from the use of this software.
  10.  
  11.     Permission is granted to anyone to use this software for any purpose,
  12.     including commercial applications, and to alter it and redistribute it
  13.     freely, subject to the following restrictions:
  14.  
  15.     1. The origin of this software must not be misrepresented; you must not
  16.        claim that you wrote the original software. If you use this software
  17.        in a product, an acknowledgment in the product documentation would be
  18.        appreciated but is not required.
  19.     2. Altered source versions must be plainly marked as such, and must not be
  20.        misrepresented as being the original software.
  21.     3. This notice may not be removed or altered from any source distribution.
  22.  
  23.  
  24.   Brennan Underwood
  25.   brennan@nullsoft.com
  26.  
  27. */
  28.  
  29. #include "tabsheet.h"
  30. #include "notifmsg.h"
  31.  
  32. #include "std.h"
  33.  
  34. #include "../studio/api.h"
  35.  
  36. #define DEFAULT_TAB_ROW_HEIGHT 20
  37.  
  38. TabSheet::TabSheet() {
  39.   tabrowheight = DEFAULT_TAB_ROW_HEIGHT;
  40.   tabrowwidth = 0;
  41.   leftscroll = rightscroll = NULL;
  42.   background = NULL;
  43.   tabrowmargin = 0;
  44.   active = NULL;
  45. }
  46.  
  47. TabSheet::~TabSheet() {
  48.   int nchildren;
  49.   ASSERT(tabs.getNumItems() == children.getNumItems());
  50.   if ((nchildren = children.getNumItems()) != 0) {
  51.     for (int i = 0; i < nchildren; i++) {
  52.       ASSERT(children[i] != NULL);
  53.       delete children[i];
  54.       ASSERT(tabs[i] != NULL);
  55.       delete tabs[i];
  56.       if (tips[i]!=(void *)-1)
  57.         FREE(tips[i]);
  58.     }
  59.   }
  60.   delete leftscroll;
  61.   delete rightscroll;
  62.   delete background;
  63. }
  64.  
  65. int TabSheet::onInit() {
  66.   TABSHEET_PARENT::onInit();
  67.   int i, nchildren;
  68.  
  69.   if (leftscroll != NULL) {
  70.     leftscroll->init(this);
  71.     leftscroll->setParent(this);
  72.   }
  73.   if (rightscroll != NULL) {
  74.     rightscroll->init(this);
  75.     rightscroll->setParent(this);
  76.   }
  77.  
  78.   nchildren = children.getNumItems();
  79. //  ASSERT(nchildren > 0);
  80.   ASSERT(tabs.getNumItems() == 0);
  81.   for (i = 0; i < nchildren; i++) {
  82.     int r = children[i]->init(this);
  83.     ASSERT(r);
  84.     children[i]->setParent(this);
  85.     TabButton *tb = tabs.addItem(new TabButton());
  86.     r = tb->init(this);
  87.     if (tips[i]!=(void *)-1)
  88.       tb->setTip(tips[i]);
  89.     ASSERT(r);
  90.     tb->setParent(this);
  91.     tb->linkWnd(children[i]);
  92.  
  93.     if (instances[i] != NULL) {
  94.       tb->setBitmaps(instances[i], normal[i], pushed[i], hilite[i], -1);
  95.     } else {
  96.       tb->setButtonText(children[i]->getName());
  97.     }
  98.  
  99.     children[i]->setVisible(i == 0);
  100.         tabs[i]->setVisible(showed.enumItem(i));
  101.   }
  102.   if (nchildren) {
  103.     active = children[0];
  104.     tabs[0]->setHilite(TRUE);
  105.   }
  106.   ASSERT(tabs.getNumItems() == children.getNumItems());
  107.   ASSERT(tabs.getNumItems() == nchildren);
  108.   onResize();
  109.   return 1;
  110. }
  111.  
  112. void TabSheet::getClientRect(RECT *r) {
  113.   TABSHEET_PARENT::getClientRect(r);
  114.   r->top += tabrowheight;
  115. }
  116.  
  117. void TabSheet::setBackgroundBmp(const char *name) {
  118.   if (background) delete background;
  119.   background = NULL;
  120.   if (name && *name)
  121.     background = new SkinBitmap(name);
  122. }
  123.  
  124. SkinBitmap *TabSheet::getBackgroundBitmap() {
  125.   return background;
  126. }
  127.  
  128. int TabSheet::onPaint(Canvas *canvas) {
  129.  
  130.   PaintBltCanvas paintcanvas;
  131.   if (canvas == NULL) {
  132.     if (!paintcanvas.beginPaintNC(this)) return 0;
  133.     canvas = &paintcanvas;
  134.   }
  135.   TABSHEET_PARENT::onPaint(canvas);
  136.  
  137.   RECT r;
  138.   TABSHEET_PARENT::getClientRect(&r);
  139.  
  140.   r.bottom = r.top + tabrowheight;
  141.  
  142.   // FUCKO: be smarter about asking buttons if their bitmaps have alpha
  143. //  api->skin_renderBaseTexture(canvas, r);
  144.  
  145.   RECT br = r;
  146.   if (leftscroll) br.left += leftscroll->getWidth();
  147.   if (rightscroll) br.right -= rightscroll->getWidth();
  148.  
  149.   if (br.right <= br.left) return 1;
  150.  
  151.   if (background != NULL) {
  152. #if 0
  153.     int i, x = tilex;
  154.     for (i = 0; ; i++) {
  155.       tile->stretch(canvas, x, 0, tile->getWidth(), tabrowheight);
  156.       x += tile->getWidth();
  157.       if (x >= r.right) break;
  158.     }
  159. #else
  160. #if 0
  161.     if (background->getAlpha()) api->skin_renderBaseTexture(canvas, br);
  162.     background->stretchToRectAlpha(canvas, &br);
  163. #else
  164.     background->stretchToRect(canvas, &br);
  165. #endif
  166. #endif
  167.   } else {
  168. #if 0
  169.     r.top = 0;
  170.     r.bottom = tabrowheight;
  171.     r.left = tilex;
  172.     r.right = tilex + tilew;
  173.     canvas->fillRect(&r, RGB(64, 64, 64));
  174. #else
  175. //    api->skin_renderBaseTexture(canvas, r);
  176. #endif
  177.   }
  178.  
  179.   return 1;
  180. }
  181.  
  182. int TabSheet::childNotify(RootWnd *which, int msg, int param1, int param2) {
  183.   if (which == leftscroll && msg == CHILD_NOTIFY_LEFTPUSH) {
  184.   }
  185.   if (which == rightscroll && msg == CHILD_NOTIFY_LEFTPUSH) {
  186.   }
  187.   return 0;
  188. }
  189.  
  190. void TabSheet::setTabRowHeight(int newheight) {
  191.   ASSERT(newheight > 0);
  192.   tabrowheight = newheight;
  193.   onResize();
  194. }
  195.  
  196. void TabSheet::setTabRowMargin(int newmargin) {
  197.   ASSERT(newmargin >= 0);
  198.   tabrowmargin = newmargin;
  199.   onResize();
  200. }
  201.  
  202. int TabSheet::addChild(BaseWnd *newchild, HINSTANCE hInst, int _normal, int _pushed, int _hilite) {
  203. return addChild(newchild, hInst, _normal, _pushed, _hilite, NULL);
  204. }
  205.  
  206. int TabSheet::addChild(BaseWnd *newchild, HINSTANCE hInst, int _normal, int _pushed, int _hilite, const char *_tip) {
  207.   children.addItem(newchild);
  208.   instances.addItem(hInst);
  209.   normal.addItem(_normal);
  210.   pushed.addItem(_pushed);
  211.   hilite.addItem(_hilite);
  212.   showed.addItem(TRUE);
  213.   tips.addItem(_tip ? STRDUP(_tip) : (char *)-1);
  214.  
  215.   return children.getNumItems()-1;
  216. }
  217.  
  218. int TabSheet::setButtonVisible(int i, BOOL state) {
  219.   showed.setItem(i, state);
  220.   if (!state && tabs.getNumItems() >= i+1)
  221.     tabs[i]->setVisible(state);
  222.   invalidate();
  223.   return 1;
  224. }
  225.  
  226. int TabSheet::addChild(BaseWnd *newchild) {
  227.   return addChild(newchild, NULL, -1, -1, -1);
  228. }
  229.  
  230. int TabSheet::addChild(BaseWnd *newchild, const char *tip) {
  231.   return addChild(newchild, NULL, -1, -1, -1, tip);
  232. }
  233.  
  234. void TabSheet::activateChild(BaseWnd *newactive) {
  235.   BaseWnd *prevactive = active;
  236.  
  237.   if (prevactive == newactive) return;    // not a switch
  238.  
  239.   RECT r;
  240.   getClientRect(&r);
  241.  
  242. #if 0
  243.   int w = r.right - r.left + 1;
  244.   int h = r.bottom - r.top + 1;
  245. #endif
  246.  
  247.   int prevpos=-1, nextpos=-1;
  248.  
  249.   for (int i = 0; i < children.getNumItems(); i++) {
  250.     if (prevactive == children[i]) prevpos = i;
  251.     if (newactive == children[i]) nextpos = i;
  252.   }
  253.  
  254.   tabs[prevpos]->setHilite(FALSE);
  255.   tabs[nextpos]->setHilite(TRUE);
  256.  
  257. #if 0
  258.   // reveal tha new winder
  259.   newactive->setVisible(TRUE);
  260.  
  261.   enable(FALSE);
  262.   prevactive->enable(FALSE);
  263.   newactive->enable(FALSE);
  264.  
  265. #define STEPS 6
  266.  
  267.   // find which window is now active
  268.   for (int c = 0; c < STEPS; c++) {
  269.     int x;
  270.     if (prevpos > nextpos) x = (w * c) / STEPS;    // right to left
  271.     else x = (w * (STEPS - c)) / STEPS;        // left to right
  272.     int y = r.top;
  273.     if (prevpos > nextpos) {
  274.       newactive->move(x - w, y);
  275.       prevactive->move(x, y);
  276.     } else {
  277.       newactive->move(x, y);
  278.       prevactive->move(x - w, y);
  279.     }
  280.     newactive->repaint();
  281.     prevactive->repaint();
  282.     Sleep(15);
  283.   }
  284. #endif
  285.  
  286.   newactive->setVisible(TRUE);
  287.   newactive->move(r.left, r.top);
  288.  
  289.   prevactive->setVisible(FALSE);
  290.   prevactive->move(r.left, r.top);
  291.  
  292.   enable(TRUE);
  293.   prevactive->enable(TRUE);
  294.   newactive->enable(TRUE);
  295.  
  296.   active = newactive;
  297. }
  298.  
  299. int TabSheet::onResize() {
  300.   TABSHEET_PARENT::onResize();
  301.  
  302.   int i, x=0;
  303.  
  304.   if (!isInited()) return 1;
  305.  
  306.   RECT r;
  307.   getClientRect(&r);
  308.  
  309.   tilew = r.right - r.left + 1;
  310.  
  311.   tilex = 0;
  312.  
  313.   if (leftscroll != NULL) {
  314.     leftscroll->resize(x, 0, leftscroll->getWidth(), tabrowheight);
  315.     x += leftscroll->getWidth();
  316.     tilew -= leftscroll->getWidth();
  317.     tilex = x;
  318.   }
  319.  
  320.   if (rightscroll != NULL) {
  321.     rightscroll->resize(r.right - rightscroll->getWidth(), 0, rightscroll->getWidth(), tabrowheight);
  322.     tilew -= rightscroll->getWidth();
  323.   }
  324.  
  325.   if (children.getNumItems() == 0 || tabs.getNumItems() == 0) return 1;
  326.   for (i = 0; i < children.getNumItems(); i++) {
  327.     ASSERT(tabs[i] != NULL);
  328.         if (!showed.enumItem(i)) continue;
  329.     int tabwidth = tabs[i]->getWidth();
  330.     if (tabwidth < 0) tabwidth = 128;
  331.     int h = (tabrowheight - tabs[i]->getHeight())/2;
  332.     tabs[i]->resize(x, h, tabwidth, tabs[i]->getHeight());
  333.     x += tabwidth + tabrowmargin;
  334. //    tilew -= tabwidth + tabrowmargin;
  335.     children[i]->resize(&r);
  336.   }
  337.   tabrowwidth = x;
  338.  
  339.   invalidate();
  340.   if (leftscroll)
  341.     leftscroll->invalidate();
  342.   if (rightscroll)
  343.     rightscroll->invalidate();
  344. //  repaint();
  345.  
  346.   return 1;
  347. }
  348.  
  349. BaseWnd *TabSheet::enumChild(int child) {
  350.   if (child < children.getNumItems())
  351.     return children[child];
  352.   else
  353.     return NULL;
  354. }
  355.  
  356. int TabSheet::getNumChild() {
  357.   return children.getNumItems();
  358. }
  359.  
  360. int TabSheet::getNumButton() {
  361.   return children.getNumItems();
  362. }
  363.  
  364. TabButton *TabSheet::enumButton(int i) {
  365.   if (i < tabs.getNumItems())
  366.     return tabs[i];
  367.   else
  368.     return NULL;
  369. }
  370.  
  371.  
  372. // TabButton
  373.  
  374. TabButton::TabButton() {
  375.   linked = NULL;
  376.   setFolderStyle(TRUE);
  377. }
  378.  
  379. void TabButton::onLeftPush(int x, int y) {
  380.   TabSheet *par;
  381.   par = (TabSheet *)getParent();
  382.   ASSERT(par != NULL);
  383.   ASSERT(linked != NULL);
  384.   par->activateChild(linked);
  385. }
  386.  
  387. void TabButton::linkWnd(BaseWnd *control) {
  388.   ASSERT(control != NULL);
  389.   linked = control;
  390. }
  391.